package cn.codingstyle.product;

import cn.codingstyle.promotion.Promotion;
import cn.codingstyle.promotion.PromotionDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Entity
@Table(name = "product")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductDO {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String barcode;
    private String name;
    private String unit;
    private BigDecimal price;
    private String type;
    @ManyToMany
    @JoinTable(
            name = "product_promotion",
            joinColumns = @JoinColumn(name = "product_id"),
            inverseJoinColumns = @JoinColumn(name = "promotion_id"))
    private List<PromotionDO> promotions = new ArrayList<>();

    public static ProductDO from(Product product) {
        return builder()
                .id(product.getId())
                .name(product.getName())
                .barcode(product.getBarcode())
                .price(product.getPrice())
                .type(product.getType())
                .unit(product.getUnit())
                .promotions(product.getPromotions().stream()
                        .map(ProductDO::convertDO)
                        .collect(Collectors.toList()))
                .build();
    }

    private static PromotionDO convertDO(Promotion promotion) {
        return PromotionDO.builder()
                .id(promotion.getId())
                .name(promotion.getName())
                .type(promotion.getType())
                .build();
    }

    public Product toEntity() {
        Product productDO = Product.builder()
                .id(id)
                .name(name)
                .barcode(barcode)
                .price(price)
                .type(type)
                .unit(unit)
                .build();
        if (Objects.nonNull(promotions)) {
            productDO.addPromotions(promotions.stream()
                    .map(PromotionDO::toEntity).collect(Collectors.toList()));
        }
        return productDO;
    }
}
